package cn.yotta.user.core.server.manager.token;

import cn.yotta.user.core.server.dto.token.TokenDto;
import cn.yotta.user.core.server.dto.user.UserDto;
import cn.yotta.user.core.server.iface.login.LoginUserContext;
import cn.yotta.user.core.server.iface.token.TokenGenerateStrategy;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @author wyaoyao
 * @date 2023/3/9 18:22
 */
@Component
@Slf4j
@AllArgsConstructor
public class TokenManagerImpl implements TokenManager {

    private final TokenGenerateStrategy tokenGenStrategy;

    private final LoginUserContext loginUserContext;

    @Override
    public TokenDto generate(UserDto userDto, Integer expireSecond) {
        // 1 生成token
        final TokenDto tokenDto = generateToken(userDto, expireSecond);
        // 2 保存登录用户的上下文
        saveLoginContext(userDto, tokenDto);
        return tokenDto;
    }

    /**
     * TODO: 这块实现的不好，有待重新实现，感觉使用JWT TOKEN姿势不太对
     */
    @Override
    public UserDto findLoginUserByToken(String token) {
        // 1 解析并校验token是否合法，可能抛出token过期异常
        final TokenGenerateStrategy.TokenParseResult tokenValue = tokenGenStrategy.decode(token);
        // 2 根据token解析获取出用户上下文
        return loginUserContext.getContext(tokenValue);
    }


    @Override
    public void loginOut(String token) {
         loginUserContext.removeContext(token);
    }


    private TokenDto generateToken(UserDto userDto, Integer expireSecond) {
        final TokenGenerateStrategy.TokenGenParam genParam = new TokenGenerateStrategy.TokenGenParam(userDto.getId(), userDto.getUsername());
        return tokenGenStrategy.generate(genParam, expireSecond);
    }

    private void saveLoginContext(UserDto userDto, TokenDto tokenDto) {
        loginUserContext.addContext(userDto, tokenDto);
    }


}
